home *** CD-ROM | disk | FTP | other *** search
Modula Implementation | 1994-09-22 | 14.0 KB | 356 lines |
- IMPLEMENTATION MODULE Install;
-
- (************************************************************************
- * Install-Modul für LPR-Modula2-Druckertreiber *
- * *
- * (c) 9/1989 by Uwe Ischebeck, Ringstr.31, 6900 Heidelberg *
- * *
- * Beschreibung im DEF-Modul *
- ************************************************************************)
-
- IMPORT GEMDOS;
-
- IMPORT Heap;
-
- FROM SYSTEM IMPORT ADR, LONG, SHORT;
-
- VAR anzahl : LONGINT;
- CRLF : ARRAY[0..1] OF CHAR;
- ZeilenLaenge : INTEGER;
-
- PROCEDURE Sloeschen;
- VAR i:INTEGER;
- BEGIN
- S.LQ:=FALSE; (* LQ-flag löschen *)
- FOR i:=0 TO MaxFunc DO (* Codetabelle löschen *)
- S.c[i]:=0 END;
- FOR i:=0 TO 255 DO (* Zeichentabelle löschen *)
- S.z[i]:=0 END;
- S.n:=NIL; (* Zeiger auf Namen löschen *)
- S.geladen:=FALSE; (* keine Anpassung geladen *)
- END Sloeschen;
-
-
- PROCEDURE ConfigPrinter( GemdosPrnOutHandle : INTEGER;
- name : ARRAY OF CHAR );
- VAR i, num, FileHandle : INTEGER;
- anzahl : LONGINT;
- ok : BOOLEAN;
- BEGIN
- ok:=FALSE;
- Sloeschen; (* Löschen aller Tabellen *)
- i:=0; (* Name der CFG-Datei in die *)
- WHILE (i<=HIGH(S.d)) & (i<=HIGH(name)) DO
- S.d[i]:=name[i]; (* Tabelle kopieren *)
- INC(i);
- END;
- GEMDOS.Open(S.d,0,FileHandle); (* CFG-Datei öffnen *)
- CfgError:=GEMDOS.ErrorNo;
- IF (CfgError=0) AND (FileHandle<0) THEN CfgError:=FileHandle END;
- IF CfgError=0 THEN
- anzahl:=SIZE(S.a); (* Datei einlesen *)
- GEMDOS.Read( FileHandle, anzahl, ADR(S.a) );
- CfgError:=GEMDOS.ErrorNo;
- IF CfgError=0 THEN
- IF GemdosPrnOutHandle>=0 THEN (* Ausgabehandle festlegen *)
- S.filehandle:=GemdosPrnOutHandle END;
- i:=0;
- WHILE (S.a[i]#0C) & (i<80) DO (* Ende des Namens finden *)
- INC(i) END; (* (durch 0C terminiert) *)
- IF i<80 THEN (* i<80: Namensende gefunden *)
- S.n:=ADR(S.a[8]); (* Name beginnt an 8.Stelle *)
- INC(i); (* 0C überspringen *)
- FOR num:=0 TO 5 DO (* Config-Parameter *)
- S.par[num]:=S.a[i]; (* übertragen *)
- INC(i)
- END;
- WHILE S.a[i]#0C DO (* Funktionstabelle 0-terminiert *)
- num:=ORD(S.a[i+1]); (* FktNummer an 2.Stelle, *)
- S.c[num]:=i; (* FktLänge an 1.Stelle *)
- i:=i+ORD(S.a[i]); (* nächste Fkt *)
- END (* Funktionen festlegen *);
- INC(i); (* 0hex überspringen *)
- WHILE S.a[i]#0C DO (* Zeichentabelle 0-terminiert *)
- num:=ORD(S.a[i+1]); (* Aufbau wie Fkt-Tabelle *)
- S.z[num]:=i;
- i:=i+ORD(S.a[i]); (* nächstes Zeichen *)
- END (* Zeichentabelle festlegen *);
- S.geladen:=TRUE; (* Flag "Anpassung geladen" *)
- END (* IF i<80 (Wahrscheinlichkeit für CFG-Datei groß) *)
- END (* IF file read *);
- ok:=GEMDOS.Close(FileHandle);
- END (* IF file opened *);
- END ConfigPrinter;
-
- PROCEDURE PrintHandle( handle : INTEGER );
- BEGIN
- IF handle>=0 THEN S.filehandle:=handle END;
- END PrintHandle;
-
- PROCEDURE PrintDirektString( str : ARRAY OF CHAR );
- VAR l : INTEGER;
- BEGIN
- l:=0;
- LOOP (* Wie lang ist "str", da evtl. nicht mit 0C terminiert *)
- IF l>HIGH(str) THEN EXIT
- ELSIF str[l]=0C THEN EXIT
- ELSE INC(l)
- END
- END;
- ZeilenLaenge:=ZeilenLaenge+l;
- anzahl:=LONG(l);
- GEMDOS.Write(S.filehandle,anzahl,ADR(str) ); (* Ausgabe *)
- END PrintDirektString;
-
- PROCEDURE PrintDirekt( c : CHAR );
- BEGIN
- IF c>37C THEN INC(ZeilenLaenge) END;
- anzahl:=1;
- GEMDOS.Write(S.filehandle,anzahl,ADR(c) );
- END PrintDirekt;
-
- PROCEDURE PrintDirektLn;
- BEGIN
- PrintDirektString(CRLF);
- ZeilenLaenge:=0;
- END PrintDirektLn;
-
- PROCEDURE IntToHex( ein : INTEGER; VAR aus : ARRAY OF CHAR);
- VAR n,h : INTEGER;
- BEGIN
- n:=HIGH(aus); (* Setzt die Integerzahl "ein" in die Zeichenkette *)
- WHILE n>=0 DO (* "aus" rechtsbündig ein. Aufgefüllt mit "0". *)
- h:=ein MOD 16;
- IF h<10 THEN aus[n]:=CHR(h+30H)
- ELSE aus[n]:=CHR(h+41H-10) END;
- ein:=ein DIV 16; DEC(n);
- END;
- END IntToHex;
-
- PROCEDURE CfgAnalyse;
- VAR s2 : ARRAY[0..1] OF CHAR;
- i,n : INTEGER;
- BEGIN
- PrintDirektString("* Name des Druckertreibers"); PrintDirektLn;
- PrintDirektString(S.n^);
- PrintDirektLn;
- PrintDirektLn;
- PrintDirektString("* Installationsvariablen"); PrintDirektLn;
- FOR i:=0 TO 5 DO
- IntToHex(ORD(S.par[i]),s2);
- IF i>0 THEN PrintDirektString(", ") END;
- PrintDirektString(s2);
- END;
- PrintDirektLn;
- PrintDirektLn;
- PrintDirektString("* Druckerfunktionen"); PrintDirektLn;
- FOR i:=1 TO MaxFunc DO
- IF S.c[i]#0 THEN
- IntToHex(i,s2); PrintDirektString(s2);
- FOR n:=2 TO ORD(S.a[S.c[i]])-1 DO
- IntToHex(ORD(S.a[S.c[i]+n]),s2);
- PrintDirektString(", ");
- IF ZeilenLaenge>=80 THEN PrintDirektLn;
- PrintDirektString("- ") END;
- PrintDirektString(s2);
- END;
- ELSE
- PrintDirektString("* ");
- IntToHex(i,s2); PrintDirektString(s2);
- FOR n:=1 TO 25 DO
- PrintDirekt(" ") END;
- PrintDirektString("* unbenutzt");
- END;
- PrintDirektLn;
- END;
- (* Tabelle mit "0" beenden: *)
- PrintDirekt("0"); PrintDirektLn; PrintDirektLn;
- PrintDirektString("* Übersetzungstabelle"); PrintDirektLn;
- FOR i:=0 TO 255 DO
- IF S.z[i]#0 THEN
- IntToHex(i,s2); PrintDirektString(s2);
- FOR n:=2 TO ORD(S.a[S.z[i]])-1 DO
- IntToHex(ORD(S.a[S.z[i]+n]),s2);
- PrintDirektString(", ");
- IF ZeilenLaenge>=80 THEN PrintDirektLn;
- PrintDirektString("- ") END;
- PrintDirektString(s2);
- END;
- FOR n:=1 TO 15-ORD(S.a[S.z[i]]) DO
- PrintDirektString(" ") END;
- PrintDirektString(" * "); PrintDirekt(CHR(i));
- IF ORD(S.a[S.z[i]])=2 THEN
- PrintDirektString(" nicht verfügbar") END;
- PrintDirektLn;
- END;
- END;
- (* Tabelle mit "0" beenden: *)
- PrintDirekt("0"); PrintDirektLn;
- END CfgAnalyse;
-
- PROCEDURE CfgInstall(HexfileName, CfgfileName : ARRAY OF CHAR);
- CONST LASize = 7167;
- TYPE LargeArray = ARRAY[0..LASize] OF CHAR;
- VAR handle, Ttop, Tpos, Tgroesse,
- CfgSize, num, hex, len : INTEGER;
- DateiEnde, ok, zeilenende, hexOk : BOOLEAN;
- T : POINTER TO LargeArray;
- status : ( namelesen, configvariablen, fkttabelle, zeichentabelle,fertig );
- PufferString : ARRAY[0..511] OF CHAR;
-
- PROCEDURE ScanArray(VAR a : ARRAY OF CHAR; VAR i : INTEGER);
- VAR c : CHAR;
- ii : INTEGER;
-
- PROCEDURE Laden;
- BEGIN
- anzahl:=LONG(Tgroesse); (* Lädt anzahl Bytes in den *)
- GEMDOS.Read(handle,anzahl,ADR(a)); (* Puffer a *)
- Tpos:=0; Ttop:=SHORT(anzahl);
- DateiEnde:=Ttop=0;
- END Laden;
-
- PROCEDURE NextC; (* Zeiger auf das nächste Zeichen setzen. Wenn *)
- BEGIN (* das Dateiende noch nicht erreicht ist, dann *)
- INC(Tpos); (* Puffer nachladen. *)
- IF Tpos>=Ttop THEN
- DateiEnde:=Ttop<Tgroesse;
- IF NOT(DateiEnde) THEN Laden END;
- END;
- END NextC;
-
- PROCEDURE SucheNaechsteZeile;
- BEGIN
- LOOP IF DateiEnde THEN EXIT END; (* Zeichen bis Zeilenende *)
- IF a[Tpos]>37C THEN NextC (* überlesen *)
- ELSE EXIT END; END (* loop *);
- LOOP IF DateiEnde THEN EXIT END; (* ALLE Kontrollzeichen *)
- IF a[Tpos]<40C THEN NextC (* ASCII<" " überlesen *)
- ELSE EXIT END; END (* loop *);
- IF a[Tpos]="-" THEN NextC; zeilenende:=DateiEnde
- ELSE zeilenende:=TRUE END;
- END SucheNaechsteZeile;
-
- PROCEDURE HexZahl(VAR hex:INTEGER; VAR ok : BOOLEAN );
- VAR c:CHAR;
- BEGIN
- ok:=FALSE; hex:=0;
- LOOP
- IF DateiEnde THEN EXIT END;
- c:=a[Tpos]; NextC;
- CASE c OF
- "0".."9": hex:=hex*16+ORD(c)-30H; ok:=TRUE;
- | "A".."F": hex:=hex*16+ORD(c)-37H; ok:=TRUE;
- ELSE EXIT END;
- END (* loop *);
- END HexZahl;
-
- BEGIN
- Laden;
- zeilenende:=FALSE; hex:=0; ok:=FALSE; CfgError:=-72;
- WHILE (i<SIZE(S.a)) & NOT(DateiEnde) DO
- c:=a[Tpos];
- CASE c OF
- 0C..37C,"*": SucheNaechsteZeile;
- ELSE
- IF status=namelesen THEN
- IF (c#" ") OR ok THEN (* Name kopieren, Leer- *)
- ok:=TRUE; S.a[i]:=c; INC(i) END; (* zeichen am Anfang ver-*)
- NextC; (* schlucken *)
- ELSE
- CASE c OF
- "0".."9","A".."F": (* das muß wohl eine *)
- HexZahl(hex,hexOk); (* Hexzahl sein *)
- IF hexOk THEN (* wirklich ? *)
- IF status=configvariablen THEN
- IF num<0 THEN num:=0 END; (* Configparameter fest- *)
- S.par[num]:=CHR(hex); S.a[i]:=CHR(hex); INC(i);
- INC(num); ok:=TRUE; (* -legen,aber nicht mehr *)
- IF num=6 THEN SucheNaechsteZeile END; (* als 6 *)
- ELSE
- IF num<0 THEN (* Funktions/Zeichen-Nr *)
- num:=hex; ii:=i; INC(i);
- IF num>0 THEN
- S.a[i]:=CHR(hex); INC(i); len:=2 END;
- ok:=TRUE;
- ELSE
- S.a[i]:=CHR(hex); INC(len); INC(i); (* Code *)
- IF len=255 THEN SucheNaechsteZeile END;
- END;
- END;
- END (* if hexOk *);
- ELSE NextC END (* case c of 0..9,A..F *);
- END (* if status=namelesen *);
- END; (* case c of 0c..37c *)
- IF zeilenende THEN
- IF ok THEN
- CASE status OF
- zeichentabelle: IF num=0 THEN S.a[ii]:=0C; status:=fertig;
- ELSE S.z[num]:=ii; S.a[ii]:=CHR(len);
- END; (* Umwandlung fertig *)
- | fkttabelle: IF num=0 THEN S.a[ii]:=0C;
- status:=zeichentabelle;
- ELSE S.c[num]:=ii; S.a[ii]:=CHR(len);
- END;
- CfgError:=-75; (* Fkt-Tabelle fertig *)
- | configvariablen: status:=fkttabelle; CfgError:=-74;
- | namelesen: S.a[i]:=0C; INC(i); status:=configvariablen;
- CfgError:=-73;
- ELSE
- END (* case status of *) ;
- END (* if ok *);
- hex:=0; num:=-1; ok:=FALSE;
- zeilenende:=FALSE; (* jetzt die nächste Zeile *)
- END (* if zeilenende *);
- IF i>=SIZE(S.a) THEN CfgError:=EBuffOv END;
- END (* while not(dateiende) *);
- IF status=fertig THEN CfgError:=0 END; (* hat wohl geklappt *)
- END ScanArray;
-
- BEGIN
- Sloeschen; CfgError:=0;
- GEMDOS.Open(HexfileName,0,handle);
- IF handle>=0 THEN
- Tgroesse:=16; (* Versuch, den Puffer so *)
- REPEAT (* groß wie möglich zu machen *)
- anzahl:=LONG(Tgroesse*1024);
- Heap.Allocate(T,anzahl);
- IF T=NIL THEN DEC(Tgroesse) END;
- UNTIL (T#NIL) OR (Tgroesse=0);
- IF T=NIL THEN (* nichteinmal 1kB angelegt *)
- Tgroesse:=SIZE(PufferString); T:=ADR(PufferString);
- ELSE (* mindestens 1kB angelegt *)
- Tgroesse:=Tgroesse*1024;
- END;
- status:=namelesen;
- S.a:="GST-CFG:"; (* WordPlus will das so. *)
- CfgSize:=8; S.n:=ADR(S.a[8]);
- ScanArray(T^,CfgSize); (* Dann wandle doch mal *)
- ok:=GEMDOS.Close(handle);
- IF Tgroesse>512 THEN (* Wenn ein Puffer ange- *)
- anzahl:=LONG(Tgroesse); (* legt wurde, muß er *)
- Heap.Deallocate(T,anzahl); (* auch wieder *)
- END; (* freigegeben werden. *)
- IF (CfgSize<=8) THEN CfgError:=-77 END; (* war wohl doch nix *)
- IF CfgError=0 THEN (* wenn's geklappt hat, *)
- GEMDOS.SFirst(CfgfileName,0,handle); (* dann CFG abspeichern *)
- IF handle=0 THEN ok:=GEMDOS.Delete(CfgfileName) END;
- GEMDOS.Create(CfgfileName,0,handle);
- IF handle>=0 THEN
- anzahl:=LONG(CfgSize);
- GEMDOS.Write(handle,anzahl,ADR(S.a));
- ok:=GEMDOS.Close(handle);
- ELSE CfgError:=handle END;
- END;
- ELSE
- CfgError:=handle; (* hab' die Datei nicht gefunden *)
- END;
- END CfgInstall;
-
- BEGIN
- S.filehandle:=3; (* Initialisieren *)
- S.geladen:=FALSE;
- CRLF[0]:=15C; CRLF[1]:=12C;
- ZeilenLaenge:=0;
- END Install.
-